/**
 * Javascript functionalities for iris
 */

// Global namespace
var IRIS = {};

/**
 * Global ajax utility methods for the application
 */
IRIS.ajaxUtil = function(){
	
	var _msgStartTyping = "Start typing...",
		_msgContinueTyping = "Continue typing...",
		_msgSearching = "Searching...",
		_msgNotFound = "Not found",
		
	/**
	 * Select callback used by auto-complete functions
	 */
	_onSelect = function(hiddenEl, itemKey) {
		$(hiddenEl).val(itemKey);
	};
	
	return {
		
		/**
		 * Performs dynamic update of dropdown/select values
		 * 
		 * @param sSelectId -
		 *            id of select element
		 * @param sMethodName -
		 *            element to be invoked via ajax
		 * @param sIdName -
		 *            parameter name
		 * @param idValue -
		 *            parameter value
		 * @param removeBlankOption -
		 * 			  removes blank option if sets to true
		 * Note: if multiple parameter is needed, simply append the values with
		 * separator (e.g. value1:value2).
		 */
		refreshSelect: function(sSelectId, sMethodName, sIdName, idValue, removeBlankOption, callback) {
			// initialize select element
			var selectEl = $('#' + sSelectId);
			if(typeof selectEl[0] != 'undefined'){
				selectEl[0].options.length = 0;
				selectEl.append("<option value='' selected='selected'>Loading...</option>");		
				successCallback = function(data) {
					selectEl[0].options.length = 0;			
					if(!removeBlankOption)
						selectEl.append("<option value=''>--Select One--</option>");
					
					$.each(data, function() {
						selectEl.append($("<option value=" + this.key + ">" + this.value
								+ "</option>"));
					});
					if (typeof callback === 'function')
						callback();
				};
				var sUrl = url_context + '/ajaxrequest.jspx?methodName=' + sMethodName + '&' + sIdName
						+ '=' + idValue;
				$.ajax({
					url : sUrl,
					type : 'GET',
					dataType : 'json',
					success : successCallback
				});
			}
		},
		
		
		/**
		 * To be used in autocomplete of text fields
		 * 
		 * @param sTextId -
		 *            id of the text field that will use autocomplete
		 * @param sHiddenId -
		 *            id of the hidden field that will contain the id of the selected
		 *            value from the autocomplete list
		 * @param sMethodName -
		 *            method to be invoked via ajax
		 * @param callback -
		 *            callback after select
		 */
		autoComplete: function(sTextId, sHiddenId, sMethodName, callback) {
			
			var textEl = $('#' + sTextId);
			var hiddenEl = $('#' + sHiddenId);
			
			var sUrl = url_context+'/ajaxrequest.jspx?methodName=' + sMethodName;
			
			// ignore auto-complete if text label is hidden
			if(!textEl.is(":visible"))
				return false;
			
			$(textEl).autocomplete({
				source : function(request, response) {
					var term = request.term,
						termLength = term.length,
						msgNoMatch = "No match found.";
					
					if (termLength == 0) { //display "Start typing"
						response([_msgStartTyping]);
						$(".ui-menu-item").addClass('inactive-ui-item');
						$(".ui-menu-item").html(_msgStartTyping);
					} else if (termLength == 1) { //display "Continue typing"
						response([_msgContinueTyping]);
						$(".ui-menu-item").addClass('inactive-ui-item');
						$(".ui-menu-item").html(_msgContinueTyping);
					} else { //start the auto-complete
						response([_msgSearching]);  //display "Searching..."
						$(".ui-menu-item").addClass('inactive-ui-item');
						$(".ui-menu-item").html(_msgSearching);
						
						//make the request for the list of options
						$.ajax({
							url : sUrl,
							type : 'GET',
							dataType : "json",
							data : {
								term : term
							},
							success : function(data) {
								if(!textEl.is(":visible"))
									return false;
								if (data.length == 0 && hiddenEl.val().length == 0) {
									response([msgNoMatch]);
//									$(".ui-menu-item").addClass('inactive-ui-item');
//									$(".ui-menu-item").html('');
									hiddenEl.val('');
									return false;
								}
								response($.map(data, function(item) {
									return {
										label : item.value,
										value : item.value,
										key : item.key
									};
								}));
							}
						});				
					}
				},
				delay : 0,
				minLength : 0,
				select : function(event, ui) {
					if (ui.item.label == '' || ui.item.label == 'more...' ) {
						var term = $(this).val();
						alert('Continue typing to filter results.');
						$(this).val('');
						$(this).val(term);
						return false;
					} else {
						_onSelect(hiddenEl, ui.item.key);
					}
				},
				close : function(event, ui) {
					if (typeof callback == 'function') {
						try {
							callback.call();
						} catch (err) {
						}
					}
				}
			});

			textEl.focus(function () {
				if(!textEl.autocomplete('widget').is(':visible')) {
					textEl.autocomplete('search');
				}
			});
		},
		
		ajaxInclude: function (url, targetDivId) {
			var args_div = { 
			    	divId: targetDivId,
			    	evaluate: true
			};
			IDEYATECH.util.loadPage(url,
			    	args_div);
		}
	};
}();

/**
 * Global html/DOM related utility methods for the application
 */
IRIS.htmlUtil = function(){
	
	return {
		/**
		 * function that will cancel out the dynamic forms such as contact number, allergy, disease at the registration page
		 * by: onz
		 */
		cancelRegistrationDynamicForm: function(formId){
			$('#'+formId).slideUp(300, function(){
				$('#'+formId).remove();
			});
		},
		
		removeRegistrationDynamicFormItem: function(elem){
			console.log(elem);
		},
		
		/**
		 * function to clear all form elements by form ID
		 */
		clearSearchPane: function(formId){
			var searchForm = document.getElementById(formId);
			var formElements = searchForm.elements;
			for (var i = 0; i < formElements.length; i++){
				if (formElements[i].type.toLowerCase() == "text"){
					//for text field element
					formElements[i].value = "";
				}else if (formElements[i].type.toLowerCase() == "select-one"){
					//for select element
					formElements[i].selectedIndex = 0;
				}else if (formElements[i].type.toLowerCase() == "textarea"){
					//for textarea element
					formElements[i].value = "";
				}else if (formElements[i].type.toLowerCase() == "hidden"){
					formElements[i].value = "";
				}
			}	
		},
		
		/**
		 * method to handle the input of numbers only in a textfield. this also allow
		 * decimals, if ever needed.
		 * 
		 * @param evt
		 * @returns {Boolean}
		 */
		isNumberKey: function(evt){
			var charCode = (evt.which) ? evt.which : event.keyCode;
			if (charCode > 31 && (charCode < 48 || charCode > 57) && charCode != 46)
				return false;

			return true;
		},
		
		/**
		 * This method will add an option into an existing select element.
		 * 
		 * @param select -
		 *            id of the select element
		 * @param optionLabel -
		 *            label of the option
		 * @param optionValue -
		 *            value of the opion
		 * @param selected -
		 *            indicator if new option will be selected or not
		 * 
		 */
		addOption: function(select, optionLabel, optionValue, selected) {
			var s = document.getElementById(select);
			var idx = s.options.length;
			s[idx] = document.createElement("option");
			s[idx].value = optionValue;
			s[idx].text = optionLabel;
			s[idx].selected = selected;
		},
		
		/**
		 * Used for downloading attachments.
		 */
		download: function(link) {
			window.open(link, 'download', 'height=200,width=400');
		},
		
		/**
		 * For breaking out of frames. Specifically for use with login.jsp, when the
		 * userSession expires.
		 * 
		 * @param none
		 * @returns none
		 */
		breakout: function() {
			if (window.top != window.self) {
				window.top.location=window.self.location;
			}
		},
		
		/**
		 * For selecting all members of a drop-down select element
		 */
		selectAll: function(selMember){
		    var i;

		    if(selMember.length != -1){
		        for (i = 0; i < selMember.length; i++) {
		            selMember[i].selected = true;              
		        }
		    }
		},
		
		/**
		 * For tranferring one option value from one drop-down select to another
		 */
		addRemoveOption: function(sel1, sel2){
		    if(sel2.value == null || sel2.value == ''){
		        alert('Please select an item to be assigned as member.');
		    }
		    
		    else{
		        var length1 = sel2.length;
		        var newlength;
		        if (sel1.length == 0)
		            newlength = 0;
		        else
		            newlength = sel1.length;
		            
		        var i;            
		        for (i = 0; i < length1; i++) {
		            if (sel2[i].selected)    {
		                sel1[newlength] = document.createElement("option");
		                sel1[newlength].value = sel2[i].value;
		                sel1[newlength].text = sel2[i].text;
		                newlength++;  
		                sel2.options[i] = null;
		                i--;
		                length1--;
		            } 
		        }
		    }            
		}
	};
}();

IRIS.StringUtil = function(){
	var _SAFECHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_.!~*'()",
		/* Determines whether the whole string is a valid URL (contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/) */
		VALID_URL_PATTERN = /^(?:https?|ftp):\/\/(?:(?:(?:(?:[a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(?:%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(?:(?:(?:\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(?:\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(?:\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(?:\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(?:(?:(?:[a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(?:(?:[a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])(?:[a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*(?:[a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(?:(?:[a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(?:(?:[a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])(?:[a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*(?:[a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(?::\d*)?)(?:\/(?:(?:(?:[a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(?:%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(?:\/(?:(?:[a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(?:%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(?:\?(?:(?:(?:[a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(?:%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(?:\#(?:(?:(?:[a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(?:%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/gi,
	
	/**
	 * Taken from: http://www.webtoolkit.info/javascript-utf8.html
	 * @method _encodeUtf8
	 */
	_encodeUtf8 = function (stringToEncode) {
		var encodedStr = "";

		var stringLength = stringToEncode.length;
		for (var n = 0; n < stringLength; n++) {	 
			var c = stringToEncode.charCodeAt(n);
			var currChar = stringToEncode.charAt(n);
			
			if(_SAFECHARS.indexOf(currChar) != -1 )
				encodedStr += currChar;
			else if (currChar == " ")
				encodedStr += "+"; // x-www-urlencoded, rather than %20
			else if (currChar == "&")
				encodedStr += "%26"; //encodeURIComponent equivalent for &
			else if (c < 128)
				encodedStr += String.fromCharCode(c);
			else if((c > 127) && (c < 2048)) {
				encodedStr += String.fromCharCode((c >> 6) | 192);
				encodedStr += String.fromCharCode((c & 63) | 128);
			}
			else {
				encodedStr += String.fromCharCode((c >> 12) | 224);
				encodedStr += String.fromCharCode(((c >> 6) & 63) | 128);
				encodedStr += String.fromCharCode((c & 63) | 128);
			}
		}

		return encodedStr;
	},

	/**
	 * Taken from: http://www.webtoolkit.info/javascript-utf8.html
	 * @method _decodeUtf8 
	 */
	_decodeUtf8 = function (stringToDecode) {
		var decodedStr = "";
		var i = 0;
		var stringLength = stringToDecode.length;
		while ( i < stringLength ) {	 
			var c = stringToDecode.charCodeAt(i);
			var currChar = stringToDecode.charAt(i);			

			if(_SAFECHARS.indexOf(currChar) != -1 ) {
				decodedStr += currChar;
				i++;
			} else if (currChar == "+") {
				decodedStr += " "; // x-www-urlencoded, rather than %20
				i++;
			} else if (c < 128) {
				var isAmpersand = false;
				if(currChar == "%") { //decode ampersand
					var subStr = stringToDecode.substr(i, i+2);
					if(subStr == "%26") {
						isAmpersand = true;
						decodedStr += "&";
						i += 3;
					}						
				}
				
				if( !isAmpersand ) {
					decodedStr += String.fromCharCode(c);
					i++;
				}
			}
			else if((c > 191) && (c < 224)) {
				var c2 = stringToDecode.charCodeAt(i+1);
				decodedStr += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				var c2 = stringToDecode.charCodeAt(i+1);
				var c3 = stringToDecode.charCodeAt(i+2);
				decodedStr += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}
		}

		return decodedStr;
	};
	
	/**
	 * Determines whether the URL is valid or not.
	 */
	var _isValidURL = function(value) {
		return VALID_URL_PATTERN.test(value);
	};

	return {
		encodeURL : function(url, isEncodeUTF8) {
			if( url == null || url.length == 0 )
				return "";
			
			if(isEncodeUTF8)
				return _encodeUtf8(url);
			
			// The Javascript escape and unescape functions do not correspond
			// with what browsers actually do...
			var HEX = "0123456789ABCDEF";
			var plaintext = url;
			var encoded = "";
			for (var i = 0; i < plaintext.length; i++ ) {
				var ch = plaintext.charAt(i);
				if (_SAFECHARS.indexOf(ch) != -1) {
					encoded += ch;
				} else if (ch == " ") {
					encoded += "+"; // x-www-urlencoded, rather than %20
				} else {
					var charCode = ch.charCodeAt(0);
					if (charCode < 255) {
						encoded += encodeURIComponent(ch);
					} else {
						encoded += "%";
						encoded += HEX.charAt((charCode >> 4) & 0xF);
						encoded += HEX.charAt(charCode & 0xF);
					}
				}
			} // end for

			return encoded;
		},

		decodeURL : function(url, isDecodeUTF8) {
			if( url == null || url.length == 0 )
				return "";
			
			if(isDecodeUTF8)
				return _decodeUtf8(url);
			
			var decodedStr = url;
			var decoded = url.replace(/\+/g," ");
			decodedStr = decodeURIComponent(decoded);
			
			return decodedStr;
		},
		
		validateURL : function(url){
			if(_isValidURL(url))
				return true;
			return false;
		},
		
		getValidUrlPattern : function() {
			return VALID_URL_PATTERN;
		}
	};
		
}();



jQuery.fn.ForceNumericOnly =
	function()
	{
	    return this.each(function()
	    {
	        $(this).keydown(function(e)
	        {
	            var key = e.charCode || e.keyCode || 0;
	            // allow backspace, tab, delete, arrows, numbers and keypad numbers ONLY
	            return (
	                key == 8 || 
	                key == 9 ||
	                key == 46 ||
	                (key >= 37 && key <= 40) ||
	                (key >= 48 && key <= 57) ||
	                (key >= 96 && key <= 105));
	        });
	    });
	};


/**
 * For evaluating string using startsWith. You can call this method usng the
 * following syntax var name = 'ABCD'; name.startsWith('AB'); // returns true
 * 
 * @param t
 * @param i
 * @returns {Boolean}
 */
String.prototype.startsWith = function(t) {
	if (t == null)
		return false;
	return (t.toLowerCase() == this.substring(0, t.length).toLowerCase());
};

$(document).ready(function() {
	
	/**
	 * Displays/hides send feedback form found at the footer. 
	 */
	
	/**
	 * Submenu item dropdown
	 * 
	 * @author AJ Albaniel
	 */
	$('#header-menu ul li').hover(function(){
		$(this).children('ul').stop();
		$(this).children('ul').hide();
		$(this).children('ul').slideDown();
	},function(){
		$(this).children('ul').stop();
		$(this).children('ul').show();
		$(this).children('ul').slideUp();
	});

	
}).on("focus", ".assign-default-val", function() {
	var $this = $(this),
		defaultVal = $this.attr("placeholder"),
		currVal = $this.val();
	
	if($.browser.msie || $.browser.mozilla) { //does not support type="number"
		if(currVal == defaultVal) {
			$this.val("");
		}
	} else { //else for other browsers
		if(currVal.length == 0) {
			$this.val(defaultVal);
		}
	}	
}).on("blur", ".assign-default-val", function() {
	var $this = $(this),
		defaultVal = $this.attr("placeholder");
	if($this.val().length == 0) {
		$this.val(defaultVal);
	}
});

/**
 * Function for showing/hiding user menu
 */
function showUserMenu(){
	$('#account-panel').fadeIn(200);
}

function hideUserMenu(){
	$('#account-panel').delay(100).fadeOut(200);
}

/**
* String manipulation utility
*/
String.prototype.between = function(prefix, suffix) {
	s = this;
	var i = s.indexOf(prefix);
	if (i >= 0) {
		s = s.substring(i + prefix.length);
	} else {
		return '';
	}
	if (suffix) {
		i = s.indexOf(suffix);
		if (i >= 0) {
			s = s.substring(0, i);
		} else {
			return '';
		}
	}
	return s;
}

function numberWithCommas(x) {
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}



/**
 * Always display main menu
 * 
 * @author AJ
 */
$(window).bind('scroll',function(e){
	var scrolled = $(window).scrollTop();
	
	if(scrolled > 20) {
		//$('#header-menu').css('position', 'fixed');
		//$('#header-menu').css('top', '-6px');
		$('#header-menu').css('-moz-box-shadow', '0 1px 1px #777');
		$('#header-menu').css('-webkit-box-shadow', '0 1px 1px #777');
		$('#header-menu').css('box-shadow', '0 1px 1px #777');
	} else {
		//$('#header-menu').css('position', 'absolute');
		//$('#header-menu').css('top', '37px');
		$('#header-menu').css('-moz-box-shadow', 'none');
		$('#header-menu').css('-webkit-box-shadow', 'none');
		$('#header-menu').css('box-shadow', 'none');
	}
	
});
